<template>
  <div id="cesiumContainer"></div>
  <div class="formContain">
    经度
    <el-input-number v-model="longitude" :precision="4" :step="0.0001" :max="180" :min="-180"
                     @change="debouncePositionChange"/>
    纬度
    <el-input-number v-model="latitude" :precision="4" :max="85" :min="-85" :step="0.0001" @change="debouncePositionChange"/>
    高度
    <el-input-number v-model="height" :precision="2" :step="10" @change="cameraChange"/>
    航向角
    <el-input-number v-model="heading" :precision="2" @change="debouncePositionChange"/>
    俯仰角
    <el-input-number v-model="pitch" :max="90" :min="-90" :precision="2" @change="debouncePositionChange"/>
    滚动角
    <el-input-number v-model="roll" :precision="2" @change="debouncePositionChange"/>
    <el-button style="margin-left: 20px" @click="handleClick">保存视角截图</el-button>
  </div>
  <div id="eye"></div>
</template>

<script setup>
// import * as Cesium from 'cesium'
import { onBeforeUnmount, onMounted, ref } from "vue";
import {
  KyViewer,
  Line,
  Marker,
  MarkerStyle,
  PolygonCube,
  PolygonStyle,
  Tileset,
} from "../plugins/cesium/index";
import {
  debounce,
  saveCesiumSceneToFile,
  useThrottled,
} from "../utils/index.js";

const longitude = ref();
const latitude = ref();
const height = ref();
const heading = ref();
const pitch = ref();
const roll = ref();
let viewer = null;
let eyeViewer = null;
let rectEntity = null;

function initMap() {
  viewer = new KyViewer("cesiumContainer", {});

  viewer.scene.debugShowFramesPerSecond = true;
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(111.204, 30.684, 2000),
  });
  viewer.camera.percentageChanged = 0.03;
  cameraPosChange();
  viewer.camera.changed.addEventListener(() => {
    cameraPosChange();
    eyeRectUpdate();
  });
  viewer.scene.preRender.addEventListener(syncViewer);
}

function initEye() {
  eyeViewer = new KyViewer("eye", {});
  eyeRectUpdate();
  syncViewer();
}

function eyeRectUpdate() {
  if (rectEntity) {
    eyeViewer.entities.removeById("rectangle");
  }
  rectEntity = {
    id: "rectangle",
    rectangle: {
      coordinates: viewer.camera.computeViewRectangle(),
      material: Cesium.Color.GREEN.withAlpha(0.5),
      // rotation: Cesium.Math.toRadians(45),
      height: 10.0,
      outline: true, // height must be set for outline to display
      outlineColor: Cesium.Color.YELLOW,
    },
  };
  eyeViewer.entities.add(rectEntity);
}

function cameraPosChange() {
  const carto = Cesium.Cartographic.fromCartesian(viewer.camera.position);
  console.log("相机位置变化", carto);
  longitude.value = Number(Cesium.Math.toDegrees(carto.longitude).toFixed(4));
  latitude.value = Number(Cesium.Math.toDegrees(carto.latitude).toFixed(4));
  height.value = Number(carto.height.toFixed(2));
  heading.value = Number(
    Cesium.Math.toDegrees(viewer.camera.heading).toFixed(2),
  );
  pitch.value = Number(Cesium.Math.toDegrees(viewer.camera.pitch).toFixed(2));
  roll.value = Number(Cesium.Math.toDegrees(viewer.camera.roll).toFixed(2));
}

const debouncePositionChange = debounce(() => {
  console.log("防抖函数触发，设置相机位置", height.value);
  viewer.camera.setView({
    destination: Cesium.Cartesian3.fromDegrees(
      longitude.value,
      latitude.value,
      height.value,
    ),
    orientation: {
      heading: Cesium.Math.toRadians(heading.value),
      pitch: Cesium.Math.toRadians(pitch.value),
      roll: Cesium.Math.toRadians(roll.value),
    },
  });
}, 200);

function cameraChange() {
  console.log("高度变化");
  debouncePositionChange();
}

let syncViewer = useThrottled(function () {
  // console.log('computeViewRectangle', window.viewer.camera.computeViewRectangle())
  if (!viewer) {
    return;
  }
  const rectangle = viewer.camera.computeViewRectangle();
  console.log(rectangle);
  const longitude = (rectangle.west + rectangle.east) / 2;
  const latitude = (rectangle.south + rectangle.north) / 2;
  let position = JSON.parse(JSON.stringify(viewer.camera.position));
  const carto = Cesium.Cartographic.fromCartesian(position);
  const height = carto.height * 1.5 + 200;
  const eyePos = Cesium.Cartesian3.fromRadians(longitude, latitude, height);
  eyeViewer.camera.flyTo({
    destination: eyePos,
    // orientation: {
    //   heading: viewer.camera.heading,
    //   pitch: viewer.camera.pitch,
    //   roll: viewer.camera.roll
    // },
    duration: 0.0,
  });
}, 500);

/**
 *
 */
function handleClick() {
  saveCesiumSceneToFile(viewer.scene);
}

onMounted(() => {
  initMap();
  initEye();
});
onBeforeUnmount(() => {
  console.log("销毁cesium");
  viewer.destroy();
  viewer = null;
  eyeViewer.destroy();
  eyeViewer = null;
});
</script>

<style scoped>
#cesiumContainer {
  width: 100%;
  height: 100vh;
}

.formContain {
  position: absolute;
  bottom: 30px;
  left: 30px;
  background-color: #777777;
  padding: 10px 10px;
}

#eye {
  position: absolute;
  width: 400px;
  height: 225px;
  bottom: 30px;
  right: 30px;
  border: 4px white solid;
}
</style>